home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / xinetd / xinetd.2.0.6 / ident.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-22  |  4.5 KB  |  239 lines

  1. /*
  2.  * (c) Copyright 1992 by Panagiotis Tsirigotis
  3.  * All rights reserved.  The file named COPYRIGHT specifies the terms 
  4.  * and conditions for redistribution.
  5.  */
  6.  
  7. static char RCSid[] = "$Id: ident.c,v 5.1 1992/11/01 00:01:21 panos Exp $" ;
  8.  
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11. #include <netinet/in.h>
  12. #include <netdb.h>
  13. #include <signal.h>
  14. #include <syslog.h>
  15. #include <setjmp.h>
  16. #include <errno.h>
  17. #include <fcntl.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20.  
  21. #include "str.h"
  22.  
  23. #include "defs.h"
  24. #include "server.h"
  25.  
  26. void msg() ;
  27.  
  28.  
  29. #define TIME_LIMIT                10        /* seconds */
  30. #define BUFSIZE                    512
  31.  
  32. #define START_TIMER()            (void) alarm( TIME_LIMIT )
  33. #define STOP_TIMER()                (void) alarm( 0 )
  34.  
  35. char *inet_ntoa() ;
  36.  
  37. status_e write_buf() ;
  38.  
  39.  
  40. static jmp_buf env ;
  41.  
  42.  
  43. static void sigalrm_handler()
  44. {
  45.     longjmp( env, 1 ) ;
  46. }
  47.  
  48.  
  49. /*
  50.  * This function always runs in a forked process.
  51.  */
  52. void log_remote_user( serp )
  53.     struct server *serp ;
  54. {
  55.     static char buf[ BUFSIZE ] ;
  56.     int cc ;
  57.     struct sockaddr_in sin_local, sin_remote, sin_contact ;
  58.     unsigned local_port, remote_port ;
  59.     int sd ;
  60.     int sin_len ;
  61.     char *p ;
  62.     char *func = "log_remote_user" ;
  63.     char *get_line(), *verify_line() ;
  64.     void logprint() ;
  65.  
  66.     if ( (int) signal( SIGALRM, sigalrm_handler ) == -1 )
  67.     {
  68.         msg( LOG_ERR, func, "signal: %m" ) ;
  69.         return ;
  70.     }
  71.  
  72.     /*
  73.      * Determine local and remote addresses
  74.      */
  75.     sin_len = sizeof( sin_local ) ;
  76.     if ( getsockname( SERVER_FD( serp ), SA( &sin_local ), &sin_len ) == -1 )
  77.     {
  78.         msg( LOG_ERR, func, "getsockname: %m" ) ;
  79.         return ;
  80.     }
  81.     sin_remote = *conn_address( SERVER_CONNECTION( serp ) ) ;
  82.     local_port = ntohs( sin_local.sin_port ) ;
  83.     remote_port = ntohs( sin_remote.sin_port ) ;
  84.  
  85.     /*
  86.      * Create a socket and set the close-on-exec flag on the descriptor
  87.      */
  88.     sd = socket( AF_INET, SOCK_STREAM, 0 ) ;
  89.     if ( sd == -1 )
  90.     {
  91.         msg( LOG_ERR, func, "socket creation: %m" ) ;
  92.         return ;
  93.     }
  94.     if ( fcntl( sd, F_SETFD, 1 ) == -1 )
  95.     {
  96.         msg( LOG_ERR, func, "fcntl F_SETFD: %m" ) ;
  97.         return ;
  98.     }
  99.  
  100.     if ( setjmp( env ) )
  101.     {
  102.         msg( LOG_ERR, func, "Timeout while contacting identity server at %s",
  103.                                         inet_ntoa( sin_remote.sin_addr ) ) ;
  104.         return ;
  105.     }
  106.  
  107.     CLEAR( sin_contact ) ;
  108.     sin_contact.sin_family = sin_remote.sin_family ;
  109.     sin_contact.sin_addr = sin_remote.sin_addr ;
  110.     sin_contact.sin_port = htons( IDENTITY_SERVICE_PORT ) ;
  111.  
  112.     START_TIMER() ;
  113.  
  114.     if ( connect( sd, SA( &sin_contact ), sizeof( sin_contact ) ) == -1 )
  115.     {
  116.         STOP_TIMER() ;
  117.         return ;
  118.     }
  119.  
  120.     cc = strx_nprint( buf, sizeof( buf ),
  121.                                         "%d,%d\r\n", remote_port, local_port ) ;
  122.     if ( write_buf( sd, buf, cc ) == FAILED )
  123.     {
  124.         STOP_TIMER() ;
  125.         return ;
  126.     }
  127.  
  128.     if ( get_line( sd, buf, sizeof( buf ) ) == NULL )
  129.     {
  130.         STOP_TIMER() ;
  131.         return ;
  132.     }
  133.     
  134.     STOP_TIMER() ;
  135.  
  136.     /*
  137.      * Verify that the received line is OK
  138.      */
  139.     if ( ( p = verify_line( buf, local_port, remote_port ) ) == NULL )
  140.     {
  141.         msg( LOG_ERR, func, "Bad line received from identity server at %s: %s",
  142.                                         inet_ntoa( sin_remote.sin_addr ), buf ) ;
  143.         return ;
  144.     }
  145.  
  146.     logprint( SERVER_CONNECTION( serp )->sp, "USERID", "%s", p ) ;
  147. }
  148.  
  149.  
  150. PRIVATE char *verify_line( line, local_port, remote_port )
  151.     char *line ;
  152.     unsigned local_port ;
  153.     unsigned remote_port ;
  154. {
  155.     char *p ;
  156.     char *start = line ;
  157.  
  158.     /*
  159.      * Verify port numbers
  160.      */
  161.     p = strchr( start, ',' ) ;
  162.     if ( p == NULL )
  163.         return( NULL ) ;
  164.     *p = NUL ;
  165.     if ( atoi( start ) != remote_port )
  166.         return( NULL ) ;
  167.     
  168.     start = p+1 ;
  169.     p = strchr( start, ':' ) ;
  170.     if ( p == NULL )
  171.         return( NULL ) ;
  172.     *p = NUL ;
  173.     if ( atoi( start ) != local_port )
  174.         return( NULL ) ;
  175.     
  176.     start = p+1 ;
  177.     for ( p = start ; isspace( *p ) ; p++ ) ;
  178.     if ( *p == NUL )
  179.         return( NULL ) ;
  180.     start = p ;
  181.     if ( strncmp( start, "USERID", 6 ) != 0 )
  182.         return( NULL ) ;
  183.     start += 6 ;        /* skip the USERID */
  184.  
  185.     /*
  186.      * Skip any white-space
  187.      */
  188.     for ( p = start ; isspace( *p ) ; p++ ) ;
  189.     if ( *p != ':' )
  190.         return( NULL ) ;
  191.     for ( p++ ; isspace( *p ) ; p++ ) ;
  192.     if ( *p == NUL )
  193.         return( NULL ) ;
  194.     return( p ) ;
  195. }
  196.  
  197.     
  198.  
  199. /*
  200.  * Get a line terminated by CR-LF.
  201.  * Replace the CR-LF with NUL.
  202.  */
  203. PRIVATE char *get_line( sd, buf, bufsize )
  204.     int sd ;
  205.     char *buf ;
  206.     unsigned bufsize ;
  207. {
  208.     int size ;
  209.     int cc ;
  210.     char *p ;
  211.     char *s ;
  212.     char *func = "get_line" ;
  213.  
  214.     for ( p = buf, size = bufsize ; size > 0 ; p += cc, size -= cc )
  215.     {
  216.         cc = read( sd, p, size ) ;
  217.         if ( cc == -1 )
  218.             if ( errno == EINTR )
  219.             {
  220.                 cc = 0 ;
  221.                 continue ;
  222.             }
  223.             else
  224.             {
  225.                 msg( LOG_ERR, func, "read: %m" ) ;
  226.                 return( NULL ) ;
  227.             }
  228.         for ( s = p ; s < p + cc ; s++ )
  229.             if ( *s == '\n' && s != buf && s[-1] == '\r' )
  230.             {
  231.                 s[-1] = NUL ;
  232.                 return( buf ) ;
  233.             }
  234.     }
  235.     msg( LOG_ERR, func, "Too much input from identity server" ) ;
  236.     return( NULL ) ;
  237. }
  238.  
  239.